package com.rayson.yututu.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rayson.yututu.constant.UserConstant;
import com.rayson.yututu.exception.BusinessException;
import com.rayson.yututu.exception.ErrorCodeEnum;
import com.rayson.yututu.exception.ThrowUtils;
import com.rayson.yututu.manager.auth.StpKit;
import com.rayson.yututu.mapper.UserMapper;
import com.rayson.yututu.model.entity.User;
import com.rayson.yututu.model.enums.UserRoleEnum;
import com.rayson.yututu.model.req.user.UserLoginReq;
import com.rayson.yututu.model.req.user.UserQueryReq;
import com.rayson.yututu.model.req.user.UserRegistReq;
import com.rayson.yututu.model.vo.LoginUserVO;
import com.rayson.yututu.model.vo.UserVO;
import com.rayson.yututu.service.UserService;
import com.rayson.yututu.util.PageUtil;
import com.rayson.yututu.util.ServletUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * @author wulei
 * @description 针对表【user(用户表)】的数据库操作Service实现
 * @createDate 2024-12-18 20:04:10
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {

    @Override
    public String regist(UserRegistReq userRegistReq) {
        log.info("用户注册:{}", userRegistReq);
        // 1.两次密码是否一致
        if (!StrUtil.equals(userRegistReq.getPassword(), userRegistReq.getCheckPassword())) {
            throw new BusinessException(ErrorCodeEnum.PARAM_ERROR, "两次密码不一致");
        }
        // 2.用户名是否已存在
        if (count(lambdaQuery().getWrapper().eq(User::getUsername, userRegistReq.getUsername())) > 0) {
            throw new BusinessException(ErrorCodeEnum.PARAM_ERROR, "用户名已存在");
        }
        // 3.密码加密
        String encryptedPassword = DigestUtil.bcrypt(userRegistReq.getPassword());
        // 4.构造用户
        User user = new User();
        user.setUsername(userRegistReq.getUsername());
        user.setPassword(encryptedPassword);
        user.setUserRole(UserRoleEnum.USER.getValue());
        // 5.保存用户信息
        boolean save = save(user);
        ThrowUtils.throwIf(!save, ErrorCodeEnum.SYSTEM_ERROR, "注册失败");
        return user.getId();
    }

    @Override
    public LoginUserVO login(UserLoginReq userLoginReq, HttpServletRequest request) {
        // 1.根据用户名查询用户信息
        User user = getOne(lambdaQuery().getWrapper().eq(User::getUsername, userLoginReq.getUsername()));
        // 2.判断用户是否存在
        if (Objects.isNull(user)) {
            throw new BusinessException(ErrorCodeEnum.PARAM_ERROR, "用户名不存在或密码错误");
        }
        // 3.校验密码是否正确
        if (!DigestUtil.bcryptCheck(userLoginReq.getPassword(), user.getPassword())) {
            throw new BusinessException(ErrorCodeEnum.PARAM_ERROR, "用户名不存在或密码错误");
        }
        // 4.保存用户登录态
        request.getSession().setAttribute(UserConstant.USER_LOGIN_SESSION_KEY, user);
        // sa-token登录及设置用户信息
        StpKit.SPACE.login(user.getId());
        StpKit.SPACE.getSession().set(UserConstant.USER_LOGIN_SESSION_KEY, user);
        // 5.返回用户信息
        LoginUserVO loginUserVO = new LoginUserVO();
        BeanUtils.copyProperties(user, loginUserVO);
        return loginUserVO;
    }

    @Override
    public User getLoginUser(HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(UserConstant.USER_LOGIN_SESSION_KEY);
        if (Objects.isNull(user) || StrUtil.isBlank(user.getId())) {
            throw new BusinessException(ErrorCodeEnum.NOT_LOGIN);
        }
        return user;
    }

    @Override
    public void logout(HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(UserConstant.USER_LOGIN_SESSION_KEY);
        if (Objects.nonNull(user) && StrUtil.isNotBlank(user.getId())) {
            request.getSession().removeAttribute(UserConstant.USER_LOGIN_SESSION_KEY);
            log.info("用户{}登出", user.getUsername());
        }
    }

    @Override
    public Page<UserVO> queryUserVOList(UserQueryReq userQueryReq) {
        return this.baseMapper.queryUserVOList(PageUtil.getPage(userQueryReq), userQueryReq);
    }

    @Override
    public boolean isAdmin(User user) {
        return Objects.nonNull(user) && UserRoleEnum.ADMIN.getValue().equals(user.getUserRole());
    }

    @Override
    public boolean isAdmin() {
        User loginUser = getCurrentUser();
        if (Objects.isNull(loginUser)) {
            return false;
        }
        return isAdmin(loginUser);
    }

    @Override
    public User getCurrentUser() {
        HttpServletRequest request = ServletUtil.getRequest();
        return getLoginUser(request);
    }

}




